package hc.server.ui;

import hc.App;
import hc.res.ImageSrc;
import hc.server.data.screen.ScreenCapturer;
import hc.util.LogServerSide;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.Highlight;
import javax.swing.text.Highlighter.HighlightPainter;

public class LogViewer extends JFrame {
	static Highlighter.HighlightPainter painterQuery = new DefaultHighlighter.DefaultHighlightPainter(
			Color.YELLOW);
	static Highlighter.HighlightPainter ERROR_LIGHTER = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
	static Highlighter.HighlightPainter OP_LIGHTER = new DefaultHighlighter.DefaultHighlightPainter(Color.GREEN);

	private void highlightErrAndOpration(JTextArea jta){
		buildHighlight(jta, LogServerSide.ERR, ERROR_LIGHTER);
		buildHighlight(jta, ScreenCapturer.OP_STR, OP_LIGHTER);
	}
	private void buildHighlight(JTextArea jta, String patternStr, HighlightPainter lighter) {
		Pattern pattern = Pattern.compile(patternStr);
		Matcher matcher = pattern.matcher(jta.getText());
		boolean matchFound = matcher.matches(); // false
		if (!matchFound) {
			while (matcher.find()) {
				matchFound = true;
				int start = matcher.start();
				int end = matcher.end();
				try {
//					Font font = new Font("Verdana", Font.BOLD, 40);
					jta.getHighlighter().addHighlight(start, end, lighter);
				} catch (BadLocationException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	public static LogViewer loadFile(Reader in, Object desc, String title) {
		// Read from file
			return new LogViewer(title, in);
//			lv.jta.read(in, null);// openAs.toString()
	}

	JPanel pnlText, pnlBody, pnlFooter;
	JButton btnSearch, btnNext, btnPre;
	JLabel jl;
	public JTextArea jta;
	Container contentpane;
	private ArrayList<Integer> searchIdx = new ArrayList<Integer>();
	int currSearchIdx;
	int searchLen;
	
	public LogViewer(String title, Reader in) {
		setTitle(title);

		setIconImage(App.SYS_LOGO);
		final JFrame self = this;
//		setModal(true);
		ActionListener exitActionListener = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				self.dispose();
			}
		};
		this.getRootPane().registerKeyboardAction(exitActionListener,
	            KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
	            JComponent.WHEN_IN_FOCUSED_WINDOW);
		

		JPanel contentpane = new JPanel();
		App.addBorderGap(getRootPane(), contentpane);
		
		contentpane.setLayout(new BorderLayout());
		pnlText = new JPanel();
		pnlBody = new JPanel();
		pnlFooter = new JPanel();
		jta = new JTextArea(20, 500);
		
		jta.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent mouseEvent)   { 
            	jta.setCursor(new Cursor(Cursor.TEXT_CURSOR));   //鼠标进入Text区后变为文本输入指针
            } 
            public void mouseExited(MouseEvent mouseEvent)   { 
            	jta.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));   //鼠标离开Text区后恢复默认形态 
            } 
        }); 
		jta.getCaret().addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e)   { 
            	jta.getCaret().setVisible(true);   //使Text区的文本光标显示 
            } 
        }); 
        
//		jta=new JTextArea("Hello");//creates text field to enter route
//	    jta.setColumns(250);
//	    jta.setRows(250);
//		jta.setBounds(50, 75, 500, 250);//sets location and size
	    jta.setEditable(false);//makes the field editable
//	    jta.setFont(new Font("Time", Font.PLAIN,12));//sets font of text
//	    jta.setBackground(null);//makes background transparents
//	    jta.setForeground(Color.BLUE);//sets colour of text
//	    jta.setBorder(BorderFactory.createEtchedBorder(3, Color.BLUE, Color.BLUE)); //sets border so text field can be seen

	    
//		jta.setFont(new Font("Serif", Font.PLAIN, 12));
//		jta.setForeground(Color.BLACK);
		// Set lineWrap and wrapStyleWord true for the text area
		jta.setLineWrap(true);
		jta.setWrapStyleWord(true);

		try {
			jta.read(in, null);
		} catch (IOException e2) {
			e2.printStackTrace();
		}

		// Create a scroll pane to hold the text area
		JScrollPane jsp = new JScrollPane(jta);

		highlightErrAndOpration(jta);
		
		// Set BorderLayout for the panel, add label and scrollpane
		pnlBody.setLayout(new BorderLayout());
		pnlBody.add(jsp, BorderLayout.CENTER);

		jl = new JLabel("");
		btnSearch = new JButton("", new ImageIcon(ImageSrc.SEARCH_ICON));
		btnNext = new JButton("", new ImageIcon(ImageSrc.DOWN_ICON));
		btnPre = new JButton("", new ImageIcon(ImageSrc.UP_ICON));
		pnlText.add(jl);
		pnlFooter.add(btnSearch);
		pnlFooter.add(btnNext);
		pnlFooter.add(btnPre);
		
		btnNext.setEnabled(false);
		btnPre.setEnabled(false);
		
//		contentpane.add(pnlText, BorderLayout.NORTH);
		contentpane.add(pnlBody, BorderLayout.CENTER);
		contentpane.add(pnlFooter, BorderLayout.SOUTH);
		setSize(1024, 700);
		
		int width = getWidth(), height = getHeight();
		setSize(width, height);

		int w = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2;
		int h = (Toolkit.getDefaultToolkit().getScreenSize().height - height) / 2;
		setLocation(w, h);
		
		setVisible(true);
		
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setResizable(false);

		this.getRootPane().setDefaultButton(btnSearch);
		
		btnNext.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jta.setCaretPosition(searchIdx.get(currSearchIdx++));
				
				btnPre.setEnabled(true);

				if(searchIdx.size() > currSearchIdx){
					btnNext.setEnabled(true);
				}else{
					btnNext.setEnabled(false);
				}
			}
		});
		
		btnPre.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				jta.setCaretPosition(searchIdx.get((--currSearchIdx) - 1));
				
				btnNext.setEnabled(true);

				if(currSearchIdx == 1){
					btnPre.setEnabled(false);
				}
			}
		});
		
		btnSearch.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String searchStr = JOptionPane.showInputDialog(self, btnSearch.getIcon(), "?", JOptionPane.PLAIN_MESSAGE);
				if(searchStr == null){
					return;
				}

				searchLen = searchStr.length();
				
				btnNext.setEnabled(false);
				btnPre.setEnabled(false);
				
				searchIdx.clear();
				
				String myWord = jta.getText();

				Highlighter h = jta.getHighlighter();
				
//				h.removeHighlight(LogViewer.painter);
				Highlighter.Highlight[] hs = h.getHighlights();
				for (int i = 0; i < hs.length; i++) {
					Highlight highlight = hs[i];
					if(highlight.getPainter() == LogViewer.painterQuery){
						h.removeHighlight(highlight);
					}
				}
				
				//Highlight(LogViewer.painter);
				
				//Pattern pattern = Pattern.compile("\\b" + searchStr + "\\b");
				Pattern pattern = Pattern.compile(searchStr);
				Matcher matcher = pattern.matcher(myWord);
				boolean matchFound = matcher.matches(); // false
				if (!matchFound) {
					while (matcher.find()) {
						matchFound = true;
						int start = matcher.start();
						searchIdx.add(start);
						int end = matcher.end();
						try {
//							Font font = new Font("Verdana", Font.BOLD, 40);
							h.addHighlight(start, end, LogViewer.painterQuery);
						} catch (BadLocationException e1) {
							e1.printStackTrace();
						}
					}
					
					if(matchFound){
						currSearchIdx = 0;
						jta.setCaretPosition(searchIdx.get(currSearchIdx++));
						if(searchIdx.size() > currSearchIdx){
							btnNext.setEnabled(true);
							btnNext.setFocusable(true);
						}
					}
//				}else {
//					JOptionPane.showMessageDialog(null, "No Match Found");
				}
			}
		});
	}
}